package br.unifor.mia.graph.setorcensitario;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class PathMatrix {

	private Map<String, Integer> indexMap = new HashMap<String, Integer>();
	
	private double[][] matrix;

	private double diameter = 0;

	private double centrality = Double.POSITIVE_INFINITY;
	
	private double averagePath = 0;

	public PathMatrix(List<String> nodes) {

		matrix = new double[nodes.size()][nodes.size()];

		for (int i = 0 ; i < nodes.size() ; i++) {
			indexMap.put(nodes.get(i), i);
		}
	}

	public void add(String startNode, String endNode, double pathValue) {
		matrix[indexMap.get(startNode)][indexMap.get(endNode)] = pathValue;
	}
	
	private double getRadius(int nodeIndex) {

		double[] nodeColumn = matrix[nodeIndex];
		double radius = 0;
		
		for (Double cost : nodeColumn) {
			if (cost > radius) {
				radius = cost;
			}
		}
		
		return radius;
	}
	
	public double getRadius(Node node) {
		return getRadius(indexMap.get(node));
	}

	public double getDiameter() {
		
		if (diameter != 0) {
			return diameter;
		}
		
		for (Integer index : indexMap.values()) {

			double radius = getRadius(index);
			if (radius > diameter) {
				diameter = radius;
			}
		}
		return diameter;
	}
	
	public double getCentrality() {
		
		if (centrality != Double.POSITIVE_INFINITY) {
			return centrality;
		}

		for (Integer index : indexMap.values()) {

			double radius = getRadius(index);
			if (radius != 0 && radius < centrality) {
				centrality = radius;
			}
		}
		return centrality;
	}
	
	public double getAveragePath() {
		
		if (averagePath != 0) {
			return averagePath;
		}
		
		double pathSum = 0;
		int numberOfPaths = 0;

		for (Integer indexColumn : indexMap.values()) {
			for (Integer indexRow : indexMap.values()) {
				if (matrix[indexRow][indexColumn] != 0) {
					pathSum += matrix[indexRow][indexColumn];
					numberOfPaths++;
				}
			}
		}

		averagePath = pathSum/numberOfPaths;
		
		return averagePath;
	}
}
